#include "FKDataRecord.h"

const QString FKDataRecord::ownData=QString("data");

FKDataRecord::FKDataRecord(FKDataRecord* parent,const QVariant& source):_row(0),_prop(0){
    _parent=parent;
    if(source.isValid()){
        QVariantMap e=source.toMap();
        QVariantMap d=e.value(ownData).toMap();
        for(QVariantMap::ConstIterator i=d.constBegin();i!=d.constEnd();++i){
            bool t;
            int p=i.key().toInt(&t);
            if(t){
                _data.insert(p,i.value());
            }
        }
        for(QVariantMap::ConstIterator i=e.constBegin();i!=e.constEnd();++i){
            bool t;
            int p=i.key().toInt(&t);
            if(t){
                _elements.insert(p,new FKDataList(this,p,i.value()));
            }
        }
    }
}

QVariant FKDataRecord::toVariant()const{
    QVariantMap v, d;
    for(QMap<int,QVariant>::ConstIterator i=_data.constBegin();i!=_data.constEnd();++i){
        d.insert(QString::number(i.key()),i.value());
    }
    v.insert(ownData,QVariant(d));
    for(QMap<int,FKDataList*>::ConstIterator i=_elements.constBegin();i!=_elements.constEnd();++i){
        v.insert(QString::number(i.key()),i.value()->toVariant());
    }
    return QVariant(v);
}

int FKDataRecord::rowCount()const{
    int rows=0;
    foreach (FKDataList* element, _elements) {
        rows=qMax(rows,element->size());
    }
    return rows;
}

int FKDataRecord::columnCount()const{
    int cols=0;
    foreach (int prop, _elements.keys()) {
        cols=qMax(cols,prop);
    }
    return cols;
}

FKDataRecord* FKDataRecord::sibling(const int& row, const int& prop)const{
    if(_parent)return _parent->subRecord(row,prop);
    return 0;
}

FKDataList* FKDataRecord::addElement(const int& prop){
    if(_elements.contains(prop))return 0;
    FKDataList* p=new FKDataList(this,prop);
    _elements.insert(prop,p);
    return p;
}

FKDataRecord* FKDataRecord::clone(FKDataRecord* parent)const{
    FKDataRecord* r=new FKDataRecord(parent);
    r->_data=_data;
    r->_row=_row;
    r->_prop=_prop;
    for(QMap<int,FKDataList*>::ConstIterator i=_elements.constBegin();i!=_elements.constEnd();++i){
        r->_elements[i.key()]=i.value()->clone(r);
    }
    return r;
}

FKDataRecord* FKDataRecord::subRecord(const int &row, const int &prop)const{
    FKDataList* subrecords=_elements.value(prop,0);
    if(subrecords){
        return subrecords->record(row);
    }
    return 0;
}

FKDataList::FKDataList(FKDataRecord* parent,const int& prop,const QVariant& source):_size(0),_prop(prop){
    _parent=parent;
    if(source.isValid()){
        QVariantList r=source.toList();
        int s=r.size();
        for(int i=0;i<s;++i){
            FKDataRecord* d=new FKDataRecord(parent,r.at(i));
            d->_row=_size++;
            d->_prop=prop;
            _data.append(d);
        }
    }
}

QVariant FKDataList::toVariant()const{
    QVariantList d;
    foreach (FKDataRecord* r, _data) {
        d.append(r->toVariant());
    }
    return QVariant(d);
}

FKDataList* FKDataList::clone(FKDataRecord* parent)const{
    FKDataList* d=new FKDataList(parent,_prop);
    foreach (FKDataRecord* r, _data) {
        d->_data.append(r->clone(parent));
    }
    d->_size=_size;
    return d;
}

FKDataRecord* FKDataList::addRecord(){
    FKDataRecord* e=new FKDataRecord(_parent);
    e->_row=_size++;
    e->_prop=_prop;
    _data.append(e);
    return e;
}

bool FKDataList::cloneRecord(const int &num, const int &multiplier){
    if(num<0 || num>=_size)return false;
    FKDataRecord* source=_data.at(num);
    for(int i=0;i<multiplier;++i){
        FKDataRecord* r=source->clone(_parent);
        r->_row=_size++;
        r->_prop=_prop;
        _data.append(r);
    }
    return true;
}
